package org.esjsoftware.v2m.rim;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Vector;

import javax.microedition.pim.Contact;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMItem;

import net.rim.blackberry.api.pdap.BlackBerryContact;
import net.rim.blackberry.api.pdap.BlackBerryContactGroup;
import net.rim.blackberry.api.pdap.BlackBerryContactList;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.FocusChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontFamily;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.DateField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.GaugeField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.RadioButtonField;
import net.rim.device.api.ui.component.RadioButtonGroup;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;

import org.esjsoftware.v2m.rim.Voice2Mobiles.HomeScreen.MessageStatusPopupScreen;
import org.esjsoftware.v2m.rim.Voice2Mobiles.HomeScreen.RecordAudioPopupScreen;
import org.esjsoftware.v2m.rim.Voice2Mobiles.HomeScreen.SendMessagePopupScreen;
import org.esjsoftware.v2m.rim.audio.AudioPlayer;
import org.esjsoftware.v2m.rim.common.Content;
import org.esjsoftware.v2m.rim.common.Messages;
import org.esjsoftware.v2m.rim.entity.ConfigurationEntity;
import org.esjsoftware.v2m.rim.listener.AudioPlayerListener;
import org.esjsoftware.v2m.rim.model.ConfigurationModel;
import org.esjsoftware.v2m.rim.proxy.AudioProxy;
import org.esjsoftware.v2m.rim.proxy.AudioRecordObserverInterface;
import org.esjsoftware.v2m.rim.proxy.MessageProxy;
import org.esjsoftware.v2m.rim.proxy.MessageStatusProxy;
import org.esjsoftware.v2m.rim.proxy.ObserverInterface;
import org.esjsoftware.v2m.rim.proxy.SendMessageProxy;
import org.esjsoftware.v2m.rim.ui.BasePopupScreen;
import org.esjsoftware.v2m.rim.ui.ErnestButtonField;
import org.esjsoftware.v2m.rim.ui.FullWidthButton;
import org.esjsoftware.v2m.rim.util.ServiceLocator;
import org.esjsoftware.v2m.rim.util.Tools;
import org.esjsoftware.v2m.rim.util.datastorage.rms.RMSHandller;
import org.esjsoftware.v2m.rim.view.AbstractScreen;
import org.esjsoftware.v2m.rim.view.ConfigurationScreen;
/**
 * 
 * @author Ernest
 *
 */
public class Voice2Mobiles extends UiApplication{
	private static final int MAX_NAME_LENGTH = 15;
	private static Screen configurationScreen;
	private static Screen selectPhoneNumberScreen;
	MessageStatusPopupScreen messageStatusPopupScreen; 
	SendMessagePopupScreen sendMessagePopupScreen;
	RecordAudioPopupScreen recordAudioPopupScreen;
	private HomeScreen homeScreen;
	private int chooseContactCount = 0;

	public static void main(String[] args) {
		Voice2Mobiles app = new Voice2Mobiles();
		app.enterEventDispatcher();
	}
	
	public Voice2Mobiles() {
		init();
	}
	
	//init the main screen
	public void init(){
		configurationScreen = (Screen)ConfigurationScreen.getInstance();
		homeScreen = new HomeScreen();
        
		String isFirstLogin = RMSHandller.Read(Content.getIS_FIRST_LOGIN_KEY());
		if (isFirstLogin.trim().equals("")) {
			pushScreen (configurationScreen);
		} else if (isFirstLogin.equals(Content.getIS_FIRST_LOGIN_VAR())) {
			pushScreen (homeScreen);
		}
	}
	
	//push the configuration screen
	public void changeScreen() {
		pushScreen(configurationScreen);
	}
	
	//push choose phone number screen
	public void pushSelectPhoneNumberScreen(){
		pushScreen(selectPhoneNumberScreen);
	}
	
	//call back the main screen
    public void hideScreen(Screen screen) {
        if (screen == null)
                return;
        synchronized (Application.getEventLock()) {
                if (screen.isDisplayed())
                        Ui.getUiEngine().popScreen(screen);
        }
    }
	
    //Inner class for Home Screen.
	public class HomeScreen extends AbstractScreen {
		EditField phoneNumberEditField;
		FullWidthButton buttonClearRMS;
		FullWidthButton buttonRecordMessage;
		FullWidthButton buttonPlayMessage;
		FullWidthButton buttonStopMessage;
		RadioButtonGroup radioButtonGroup;
		RadioButtonField sendNowRadioButtonField;
		RadioButtonField sendLaterRadioButtonField;
		FullWidthButton buttonSendMessage;
		FullWidthButton buttonMessageStatus;
		DateField sendTime;
		int sendTimeIndex = 0;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		MessageProxy mp = new MessageProxy();
		AudioProxy audioProxy;
		
		DateField dateField;
		
		//constructor
		public HomeScreen () {
			setTitle (Messages.getTITLE_HOME());
			
			phoneNumberEditField = new EditField(Messages.getMSG_TO(), "", Content.getMAX_PHONE_NUMBER_LENGTH() , EditField.FILTER_PHONE);
			phoneNumberEditField.setChangeListener(new FieldChangeListener() {
				public void fieldChanged(Field field, int context){
					if(phoneNumberEditField.getText().length() >= 7){
						buttonRecordMessage.setEditable(true);
					} else {
						buttonRecordMessage.setEditable(false);
						buttonPlayMessage.setEditable(false);
						buttonSendMessage.setEditable(false);
					}
				}
			});
			phoneNumberEditField.setFocusListener(new FocusChangeListener(){
				public void focusChanged(Field fild, int eventType){
					removeMenuItem();
					if (chooseContactCount % 2 == 0){
						setMenuItem();
					} else {
						addMenuItem();
					}
					chooseContactCount ++;
				}
			});
	        add(phoneNumberEditField);

			buttonRecordMessage = new FullWidthButton(Messages.getMSG_RECORD_MESSAGE());
			buttonRecordMessage.setChangeListener(new FieldChangeListener() {
				public void fieldChanged(Field field, int context){
					popRecordConfirm();
				}
			});
			buttonRecordMessage.setEditable(false);
			add(buttonRecordMessage);
			buttonPlayMessage = new FullWidthButton(Messages.getMSG_PLAY_MESSAGE());
			buttonPlayMessage.setChangeListener(new FieldChangeListener() {
				public void fieldChanged(Field field, int context) {
					if (buttonPlayMessage.getLabel().equals(Messages.getMSG_PLAY_MESSAGE())){
						buttonPlayMessage.setLabel(Messages.getMSG_STOP_PLAY_MESSAGE());
						audioProxy.setListener(new AudioPlayerListener() {
							public void listener() {
								UiApplication.getUiApplication().invokeLater(new Runnable() {
						            public void run () {
						            	buttonPlayMessage.setLabel(Messages.getMSG_PLAY_MESSAGE());
						            }
						        });
							}
						});
						audioProxy.playAudio();
					} else if (buttonPlayMessage.getLabel().equals(Messages.getMSG_STOP_PLAY_MESSAGE())) {
						buttonPlayMessage.setLabel(Messages.getMSG_PLAY_MESSAGE());
						audioProxy.setListener(new AudioPlayerListener() {
							public void listener() {
								buttonPlayMessage.setLabel(Messages.getMSG_PLAY_MESSAGE());
							}
						});
						audioProxy.stopAudioPlayer();
					}
				}
			});
			buttonPlayMessage.setEditable(false);
			add(buttonPlayMessage);
			
			buttonStopMessage = new FullWidthButton(Messages.getMSG_PLAY_MESSAGE());
			
			radioButtonGroup = new RadioButtonGroup();
			sendNowRadioButtonField = new RadioButtonField(Messages.getMSG_SEND_NOW_MESSAGE(), radioButtonGroup, true);
			sendNowRadioButtonField.setChangeListener(new FieldChangeListener(){
				public void fieldChanged(Field field, int context){
					if (sendNowRadioButtonField.isSelected()){
						selectSendType(0);
					}
				}
			});
			sendLaterRadioButtonField = new RadioButtonField(Messages.getMSG_SEND_LATER_MESSAGE(), radioButtonGroup, false);
			sendLaterRadioButtonField.setChangeListener(new FieldChangeListener(){
				public void fieldChanged(Field field, int context) {
					if (sendLaterRadioButtonField.isSelected()){
						selectSendType(1);
					}
				}
			});
			add(sendNowRadioButtonField);
			add(sendLaterRadioButtonField);
			
			Date date = new Date();
			sendTime = new DateField(Messages.getMSG_SEND_TIME_MESSAGE(), date.getTime(), DateField.DATE_TIME);
			
			buttonSendMessage = new FullWidthButton(Messages.getMSG_SEND_MESSAGE());
			buttonSendMessage.setChangeListener(new FieldChangeListener(){
				public void fieldChanged(Field field, int context) {
					if (ServiceLocator.getContactionString().equals("")) {
						messageDialog(Messages.getMSG_NO_INTERNET());
					} else {
						ConfigurationModel cm = new ConfigurationModel();
						ConfigurationEntity ce = cm.getConfiguration();
						sendMessagePopupScreen = new SendMessagePopupScreen(Messages.getMSG_SENDING_MESSAGE());
						if (radioButtonGroup.getSelectedIndex() == 0) {
							sendMessagePopupScreen.show(ce.getUserName(), ce.getPassword(), ce.getSender(), phoneNumberEditField.getText(), baos.toByteArray(), "0");
						} else if (radioButtonGroup.getSelectedIndex() == 1) {
							long scheduledTime = sendTime.getDate()/1000;
							Date d = new Date ();
							d.getTime();
	
							if (scheduledTime < (d.getTime()/1000)) {
								messageDialog(Messages.getMSG_INVALID_SCHEDULE());
							} else {
								sendMessagePopupScreen.show(ce.getUserName(), ce.getPassword(), ce.getSender(), phoneNumberEditField.getText(), baos.toByteArray(), "" + scheduledTime);
//								String response = mp.sendMessage(ce.getUserName(), ce.getPassword(), ce.getSender(), phoneNumberEditField.getText(), baos.toByteArray(), "" + scheduledTime);
//								String[] result = Tools.slipt(response, Content.getRESPONSE_SLIPT_CHARTS());
//								String responseErrorCode = result[0];
//								String responseTitle = result[1];
//								String responseMessage = result[2];
//								messageDialog(responseMessage);
							}
						}
					}
				}
			});
			buttonSendMessage.setEditable(false);
			add(buttonSendMessage);
			
			buttonMessageStatus = new FullWidthButton(Messages.getMSG_MESSAGE_STATUS_MESSAGE());
			buttonMessageStatus.setChangeListener(new FieldChangeListener(){
				public void fieldChanged(Field field, int context){
					getMessageStatus();
				}
			});
			add(buttonMessageStatus);
			phoneNumberEditField.setFocus();
		}
		
		//get message status implements
		public void getMessageStatus(){
			if (ServiceLocator.getContactionString().equals("")) {
				messageDialog(Messages.getMSG_NO_INTERNET());
			} else {
				ConfigurationModel cm = new ConfigurationModel();
				ConfigurationEntity ce = cm.getConfiguration();
				messageStatusPopupScreen = new MessageStatusPopupScreen(Messages.getMSG_GETTING_MESSAGE_STATUS());
				messageStatusPopupScreen.show(ce.getUserName(), ce.getPassword(), ce.getSender());
			}
		}
		
		//send now and send later feature, show and hidden the data selecter.
		private void selectSendType(int index){
			if (index == 0) {
				delete(sendTime);
			} else if (index == 1){
				delete(buttonSendMessage);
				delete(buttonMessageStatus);
				add(sendTime);
				add(buttonSendMessage);
				add(buttonMessageStatus);
			}
		}
		
		//Speak now popup
		private void popRecordConfirm(){
			String[] recordButton = new String[] {Messages.getMSG_RECORD_MESSAGE_BUTTON()};
			if(Dialog.ask(Messages.getMSG_RECORD_MESSAGE_CONTENT(), recordButton, 0) == 0) {
			    recordAudioPopupScreen = new RecordAudioPopupScreen("Speak now!");
			    recordAudioPopupScreen.show();
			}
		}
		
		//Choose contact feature
		private void chooseContact(){
            BlackBerryContactList contactList = null;
            try {
                    contactList = (BlackBerryContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY);
            } catch (Exception e) {
                    e.printStackTrace();
                    return;
            }
            PIMItem item = contactList.choose();
            if(item instanceof BlackBerryContact){
            	BlackBerryContact contact = (BlackBerryContact) item;
                if (contact == null){
                	return;
                }
        		String displayName = getDisplayNameByContact(contact);
        		Vector phoneNumbers = getAvailablePhoneNumbers(contact);
        		if (phoneNumbers.size() == 0){
        			Dialog.alert(Messages.getMSG_NO_PHONE_NUMBERS());
        			return;
        		} else {
            		selectPhoneNumberScreen = (Screen)new ChoosePhoneNumberScreen(phoneNumbers, displayName);
            		pushSelectPhoneNumberScreen();
        		}
            }else if (item instanceof BlackBerryContactGroup) {
            	return;
            }
		}
		
		//get the display name by contact
		public String getDisplayNameByContact(Contact contact) {
			if (contact.countValues(Contact.NAME) == 0)
				return getOrgName(contact);
			String[] name = contact.getStringArray(Contact.NAME, 0);
			String formattedName = getFormattedName(name[1], name[0]);
			if (isBlank(formattedName))
				formattedName = getOrgName(contact);
			return formattedName;
		}
		
		//get the object it's blank or no
		public boolean isBlank(Object obj) {
			return null == obj || obj.toString().trim().equals("");
		}

		//estimate the object is not blank
		public boolean isNotBlank(Object string) {
			return !isBlank(string);
		}
		
		//get the organization name from contact
		private String getOrgName(Contact contact) {
			String orgName = contact.getString(Contact.ORG, 0);
			if (isBlank(orgName)) {
				return "";
			}
			return orgName;
		}
		
		//format name with first name and last name
		public String getFormattedName(String firstName, String lastName) {
			if (isNotBlank(firstName)) {
				if (firstName.length() > MAX_NAME_LENGTH) {
					if (isNotBlank(lastName)) {
						firstName = firstName.substring(0, MAX_NAME_LENGTH - 2);
						lastName = lastName.substring(0, 1);
						return firstName + " " + lastName + ".";
					} else {
						firstName = firstName.substring(0, MAX_NAME_LENGTH);
						return firstName + ".";
					}
				} else {
					String fullName;
					if (isNotBlank(lastName))
						fullName = firstName + " " + lastName;
					else
						fullName = firstName;
					if (fullName.length() > MAX_NAME_LENGTH) {
						fullName = fullName.substring(0, MAX_NAME_LENGTH).trim();
						return fullName + ".";
					} else {
						return fullName;
					}
				}
			}
			if (isNotBlank(lastName)) {
				if (lastName.length() > MAX_NAME_LENGTH) {
					lastName = lastName.substring(0, MAX_NAME_LENGTH);
					return lastName + ".";
				} else {
					return lastName;
				}
			}
			return "";
		}
		
		//get the phone numbers from contact
		public Vector getAvailablePhoneNumbers(Contact contact) {
			int count = contact.countValues(BlackBerryContact.TEL);
			Vector phoneNumbers = new Vector();
			for (int i = 0; i < count; i++) {
				String name = "";
				if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_MOBILE) {
					name = "Mobile";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_WORK) {
					name = "Work";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_HOME) {
					name = "Home";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_PAGER) {
					name = "Pager";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_FAX) {
					name = "Fax";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_OTHER) {
					name = "Other";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_HOME2) {
						name = "Home 2";
				} else if (contact.getAttributes(BlackBerryContact.TEL, i) == BlackBerryContact.ATTR_WORK2) {
						name = "Work 2";
				}
				if (isBlank(name))
					name = "Other";
				phoneNumbers.addElement(name + ": " + contact.getString(BlackBerryContact.TEL, i));
			}
			return phoneNumbers;
		}
		
		//change the play message and send message buttons's status
		private void hasRecorded(){
			if (baos.size() > 0){
				buttonPlayMessage.setEditable(true);
				buttonSendMessage.setEditable(true);
			}
		}
		
		//add menu items at first login
		private void setMenuItem(){
			this.addMenuItem(_chooseContactMenuItem);
			this.addMenuItem(_configureMenuItem);
			this.addMenuItem(_messageStatusMenuItem);
			this.addMenuItem(_aboutMenuItem);
		}
		
		//remove all menu item
		private void removeMenuItem(){
			this.removeAllMenuItems();
		}
		
		//add menu items that the focus on phone number edit field
		private void addMenuItem(){
			this.addMenuItem(_configureMenuItem);
			this.addMenuItem(_messageStatusMenuItem);
			this.addMenuItem(_aboutMenuItem);
		}
		
		//regist choose contact menu item listener
		private MenuItem _chooseContactMenuItem = new MenuItem(Messages.getMSG_MENU_CHOOSE_CONTACT(), 0, 0) {
			public void run() {
				chooseContact();
			}
		};
		
		//regist configure menu item listener
	    private MenuItem _configureMenuItem = new MenuItem(Messages.getMSG_MENU_CONFIGURATION() , 0, 0) {
	        public void run() {
	        	changeScreen();
	        }
	    };
	    
	    //regist message status menu item listener
	    private MenuItem _messageStatusMenuItem = new MenuItem(Messages.getMSG_MENU_MESSAGE_STATUS(), 0, 0) {
	    	public void run() {
	    		getMessageStatus();
	    	}
	    };
	    
	    //regist about menu item listener
	    private MenuItem _aboutMenuItem = new MenuItem(Messages.getMSG_MENU_ABOUT(), 0, 0) {
	    	public void run() {
	    		messageDialog(Messages.getMSG_ABOUT());
	    	}
	    };
	    
	    //inner class of choose phone number screen
		class ChoosePhoneNumberScreen extends BasePopupScreen {

			private HorizontalFieldManager[] _buttonManager;
			private HorizontalFieldManager _labelManager;
			private VerticalFieldManager buttonScollManager = new VerticalFieldManager(
					Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR
							| VerticalFieldManager.FIELD_HCENTER);
			private ErnestButtonField[] _button;
			
			//constructor
			public ChoosePhoneNumberScreen(Vector phoneNumbers, final String displayName) {
				super.title.setText(displayName);
				_labelManager = new HorizontalFieldManager(
						HorizontalFieldManager.FIELD_HCENTER);
				_labelManager.add(new LabelField("Choose a phone number"));
				try {
					_labelManager.setFont(FontFamily.forName("BBAlpha Sans").getFont(
							Font.BOLD, 20));
				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				_labelManager.setPadding(0, 0, 5, 0);
				add(_labelManager);
				_buttonManager = new HorizontalFieldManager[phoneNumbers.size()];
				_button = new ErnestButtonField[phoneNumbers.size()];
				for (int i = 0; i < _buttonManager.length; i++) {
					_buttonManager[i] = new HorizontalFieldManager(
							HorizontalFieldManager.FIELD_HCENTER);
					try {
						_buttonManager[i].setFont(FontFamily.forName("BBAlpha Sans")
								.getFont(Font.BOLD, 20));
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					_buttonManager[i].setMargin(0, 0, 2, 0);
					try {
						_button[i] = new ErnestButtonField((String) phoneNumbers.elementAt(i), Integer.parseInt("FF790F", 16), FontFamily.forName("BBAlpha Sans").getFont(Font.BOLD, 20)) {
							 protected boolean navigationClick(int status, int time) {
								 String phoneNumber = this.getLabel();
								 phoneNumber = phoneNumber.substring(phoneNumber.indexOf(":") + 1);
								 phoneNumberEditField.setText(phoneNumber);
								 hideScreen(selectPhoneNumberScreen);
								 return super.trackwheelClick(status, time);
							 }
						};
					} catch (NumberFormatException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					_buttonManager[i].add(_button[i]);
					buttonScollManager.add(_buttonManager[i]);
				}
				add(buttonScollManager);
			}
		}
		
		//inner class of send message popup screen
		class SendMessagePopupScreen extends PopupScreen implements ObserverInterface {
		    private GaugeField _gaugeField = null; // Indicator to user that things are happening
		    private ButtonField _cancelButton = null; // Button user can use to get out
		    private LabelField _statusText = null;

		    private SendMessageProxy _requestThread = null;
		    private int _returnCode = ObserverInterface.CANCELLED;
		    
		    //constructor
		    public SendMessagePopupScreen(String title) {
		        super(new VerticalFieldManager());
		        this.add(new LabelField(title, LabelField.FIELD_HCENTER));
		        this.add(new SeparatorField());
		        _cancelButton = new ButtonField("Cancel", ButtonField.FIELD_HCENTER | ButtonField.CONSUME_CLICK);
		        _cancelButton.setChangeListener( new FieldChangeListener() {
		            public void fieldChanged(Field field, int context) {
		                if ( _requestThread != null ) {
		                    if ( _requestThread.isAlive() ) {
		                        _requestThread.stop();
		                        // This will send us a 'failure' notification
		                    }
		                } else {
		                    // Something has gone really wrong?!
		                    throw new RuntimeException("Oppsss");
		                }
		            }
		        });
		        this.add(_cancelButton);
		        _cancelButton.setFocus();
		    }

		    public int show(String username, String password, String sourcePhoneNumber, String destinationPhoneNumber, byte[] audioMessageData, String scheduleDatetimeString) {
		        _requestThread = new SendMessageProxy(username, password, sourcePhoneNumber, destinationPhoneNumber, audioMessageData, scheduleDatetimeString, this);
		        _requestThread.start();
		        UiApplication.getUiApplication().pushModalScreen(this);
		        return _returnCode;
		    }


		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processStatusUpdate(final int status, final String statusString) {
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		                _statusText.setText(statusString);
		                if ( status > 0 ) {
		                    _gaugeField.setValue(status);
		                }
		                SendMessagePopupScreen.this.invalidate();
		            }
		        });
		    }

		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processResponse(final byte [] responseBytes) {
		        _returnCode = ObserverInterface.OK;
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		            	UiApplication.getUiApplication().popScreen(SendMessagePopupScreen.this);
						String[] result = Tools.slipt(new String(responseBytes), Content.getRESPONSE_SLIPT_CHARTS());
//						String responseErrorCode = result[0];
//						String responseTitle = result[1];
						String responseMessage = result[2];
						phoneNumberEditField.setText("");
		                Dialog.alert(responseMessage);
		            }
		        });
		    }
		            
		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processError(int errorCode, final String errorMessage) {
		        _returnCode = errorCode;
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		            	UiApplication.getUiApplication().popScreen(SendMessagePopupScreen.this);
		                Dialog.alert(errorMessage);
		            }
		        });
		    }

		
		}
		
		//inner class of MessageStatusPopuScreen
		class MessageStatusPopupScreen extends PopupScreen implements ObserverInterface {
		    private GaugeField _gaugeField = null; // Indicator to user that things are happening
		    private ButtonField _cancelButton = null; // Button user can use to get out
		    private LabelField _statusText = null;

		    private MessageStatusProxy _requestThread = null;
		    private int _returnCode = ObserverInterface.CANCELLED;
		    
		    //constructor
		    public MessageStatusPopupScreen(String title) {
		        super(new VerticalFieldManager());
		        this.add(new LabelField(title, LabelField.FIELD_HCENTER));
		        this.add(new SeparatorField());
		        _cancelButton = new ButtonField("Cancel", ButtonField.FIELD_HCENTER | ButtonField.CONSUME_CLICK);
		        _cancelButton.setChangeListener( new FieldChangeListener() {
		            public void fieldChanged(Field field, int context) {
		                if ( _requestThread != null ) {
		                    if ( _requestThread.isAlive() ) {
		                        _requestThread.stop();
		                        // This will send us a 'failure' notification
		                    }
		                } else {
		                    // Something has gone really wrong?!
		                    throw new RuntimeException("Oppsss");
		                }
		            }
		        });
		        this.add(_cancelButton);
		        _cancelButton.setFocus();
		    }

		    public int show(String username, String password, String sourcePhoneNumber) {
		        _requestThread = new MessageStatusProxy(username, password, sourcePhoneNumber, this);
		        _requestThread.start();
		        UiApplication.getUiApplication().pushModalScreen(this);
		        return _returnCode;
		    }


		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processStatusUpdate(final int status, final String statusString) {
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		                _statusText.setText(statusString);
		                if ( status > 0 ) {
		                    _gaugeField.setValue(status);
		                }
		                MessageStatusPopupScreen.this.invalidate();
		            }
		        });
		    }

		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processResponse(final byte [] responseBytes) {
		        _returnCode = ObserverInterface.OK;
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		            	UiApplication.getUiApplication().popScreen(MessageStatusPopupScreen.this);
						String[] result = Tools.slipt(new String(responseBytes), Content.getRESPONSE_SLIPT_CHARTS());
						String responseErrorCode = result[0];
						String responseTitle = result[1];
						String responseMessage = result[2];
		                Dialog.alert(responseMessage);
		                
		            }
		        });
		    }
		            
		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processError(int errorCode, final String errorMessage) {
		        _returnCode = errorCode;
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		            	UiApplication.getUiApplication().popScreen(MessageStatusPopupScreen.this);
		                Dialog.alert(errorMessage);
		            }
		        });
		    }
		}
		
		//inner class of RecordAudioPopupScreen
		class RecordAudioPopupScreen extends PopupScreen implements AudioRecordObserverInterface {
		    private GaugeField _gaugeField = null; // Indicator to user that things are happening
		    private ButtonField _cancelButton = null; // Button user can use to get out
		    private LabelField _statusText = null;

		    private int _returnCode = ObserverInterface.CANCELLED;
		    
		    //constructor
		    public RecordAudioPopupScreen(String title) {
		        super(new VerticalFieldManager());
		        this.add(new LabelField(title, LabelField.FIELD_HCENTER));
		        this.add(new SeparatorField());
		        _cancelButton = new ButtonField("Stop", ButtonField.FIELD_HCENTER | ButtonField.CONSUME_CLICK);
		        _cancelButton.setChangeListener( new FieldChangeListener() {
		            public void fieldChanged(Field field, int context) {
		                if (audioProxy != null) {
		                    if (audioProxy.isAlive()) {
		                    	audioProxy.stop();
		                        baos = audioProxy.getAudio();
		                        hasRecorded();
		                        // This will send us a 'failure' notification
		                    }
		                } else {
		                    // Something has gone really wrong?!
		                    throw new RuntimeException("Oppsss");
		                }
		            }
		        });
		        this.add(_cancelButton);
		        _cancelButton.setFocus();
		    }

		    public int show() {
		    	audioProxy = new AudioProxy(this);
		    	audioProxy.start();
		        UiApplication.getUiApplication().pushModalScreen(this);
		        return _returnCode;
		    }


		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processStatusUpdate(final int status, final String statusString) {
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		                _statusText.setText(statusString);
		                if ( status > 0 ) {
		                    _gaugeField.setValue(status);
		                }
		                RecordAudioPopupScreen.this.invalidate();
		            }
		        });
		    }

		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processResponse(final ByteArrayOutputStream responseBytes) {
		        _returnCode = ObserverInterface.OK;
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		            	UiApplication.getUiApplication().popScreen(RecordAudioPopupScreen.this);
		            	baos = responseBytes;
		            	hasRecorded();
		                Dialog.alert("Voice message recorded.");
		                
		            }
		        });
		    }

		    /**
		     * This method is called by the Background Thread
		     * So we need to gain access to the Event Thread to update our Ui.
		     */
		    public void processError(int errorCode, final String errorMessage) {
		        _returnCode = errorCode;
		        UiApplication.getUiApplication().invokeLater(new Runnable() {
		            public void run () {
		            	UiApplication.getUiApplication().popScreen(RecordAudioPopupScreen.this);
		                Dialog.alert(errorMessage);
		            }
		        });
		    }
		}
		
        /**
         * Prevents the save dialog from being displayed
         * 
         * @see net.rim.device.api.ui.container.MainScreen#onSavePrompt()
         */
        public boolean onSavePrompt()
        {
            return true;
        }
	}
}
